package com.daily.pump.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.OvershootInterpolator;

import androidx.annotation.Nullable;

import com.daily.pump.utils.DensityUtils;


/**
 * Created by liyu on 17/8/3.
 */
public class CompressProgress extends View {

    private Paint paint, tmpPaint, textPaint, strokePain;
    private RectF rect;
    private int backGroundColor;    //背景色
    private float pointLength;      //指针长度
    private float per;             //指数百分比
    private float perPoint;        //缓存(变化中)指针百分比
    private float length;          //仪表盘半径
    private float r;

    private float mLastX;
    private float dx;

    private int mWidth, mHeight;

    private int finish_start_color, finish_end_color, unfinish_start_color, unfinish_end_color;

    private int mStrokeWidth;

    /**
     * 处理多点触控的情况，准确地计算Y坐标和移动距离dy
     * 同时兼容单点触控的情况
     */
    private int mActivePointerId = MotionEvent.INVALID_POINTER_ID;

    /**
     * 是否正在触碰
     */
    private boolean isTouching;

    public CompressProgress(Context context) {
        super(context);
        init();
    }

    public CompressProgress(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        mWidth = MeasureSpec.getSize(widthMeasureSpec);
        mHeight = mWidth;
        initIndex(mWidth / 2);
        //优化组件高度
        setMeasuredDimension(mWidth, mHeight);
    }

    private void initIndex(int specSize) {
        backGroundColor = Color.parseColor("#979498");
        r = specSize;
        length = r / 4 * 3;
        pointLength = -(float) (r * 0.66);
    }

    private void init() {
        paint = new Paint();
        rect = new RectF();
        textPaint = new Paint();
        tmpPaint = new Paint();
        strokePain = new Paint();

        finish_start_color = Color.parseColor("#8EECFC");
        finish_end_color = Color.parseColor("#55aebf");
        unfinish_start_color = Color.parseColor("#444041");
        unfinish_end_color = Color.parseColor("#4D4D4D");
        mStrokeWidth = DensityUtils.dp2px(getContext(), 6);
    }

    public CompressProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public void setR(float r) {
        this.r = r;
        this.length = r / 4 * 3;
    }

    @Override
    protected void onDraw(Canvas canvas) {

        //颜色指示的环
        initRing(canvas);
    }

    public void setBackGroundColor(int color) {
        this.backGroundColor = color;
    }

    public void setPointLength1(float pointLength1) {
        this.pointLength = -length * pointLength1;
    }

    //#3D494A
    private void initRing(Canvas canvas) {
        paint.setAntiAlias(true);
        paint.setStrokeWidth(2);
        canvas.save();
        canvas.translate(canvas.getWidth() / 2, r);

        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(mStrokeWidth);
        paint.setColor(unfinish_start_color);
        rect = getRectF(-length, -length, length, length);
        canvas.drawArc(rect, 135, 270, false, paint);

        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(mStrokeWidth);
        paint.setColor(finish_start_color);
        paint.setShader(null);
        rect = getRectF(-length, -length, length, length);
        canvas.drawArc(rect, 135, perPoint * 270, false, paint);
    }

    /**
     * Desc:获取矩阵
     * <p>
     * Author: [李豫]
     * Date: 2020-09-01
     *
     * @return rect f
     */
    private RectF getRectF(float left, float top, float right, float bottom) {
        if (rect == null) {
            rect = new RectF();
        }
        rect.left = left;
        rect.top = top;
        rect.right = right;
        rect.bottom = bottom;
        return rect;
    }

    /**
     * Desc:设置进度条
     * <p>
     * Author: [李豫]
     * Date: 2020-09-05
     *
     * @param per
     */
    public void setProgress(float per) {
        if (!isTouching){
            float perOld = this.per;
            this.per = per;
            ValueAnimator va = ValueAnimator.ofFloat(perOld, per);
            va.setDuration(1000);
            va.setInterpolator(new OvershootInterpolator());
            va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    if (!isTouching){
                        perPoint = (float) animation.getAnimatedValue();
                        invalidate();
                    }
                }
            });
            va.start();
        }
    }

    /**
     * Desc:更新进度条
     * <p>
     * Author: [李豫]
     * Date: 2020-09-05
     *
     * @param per
     */
    public void updateProgress(float per) {
        if (!isTouching){
            float perOld = this.per;
            this.per = per;
            ValueAnimator va = ValueAnimator.ofFloat(perOld, per);
            va.setDuration(1000);
            va.setInterpolator(new OvershootInterpolator());
            va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    if (!isTouching){
                        perPoint = (float) animation.getAnimatedValue();
                        invalidate();
                    }
                }
            });
            va.start();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN: {
                isTouching = true;
                final int pointerIndex = ev.getActionIndex();
                final float x = ev.getX(pointerIndex);
                mLastX = x;
                mActivePointerId = ev.getPointerId(0);
                break;
            }
            case MotionEvent.ACTION_MOVE: {
                final int pointerIndex = ev.findPointerIndex(mActivePointerId);
                final float x = ev.getX(pointerIndex);
                float y = ev.getY(pointerIndex);
                dx = x - mLastX;
                mLastX = x;
                doMove(dx, x, y);
                break;
            }
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                isTouching = false;
                mActivePointerId = MotionEvent.INVALID_POINTER_ID;
//                if (isMoving) {//手指移动，才重置音乐播放
//                    isMoving = false;
//                    resetMusicPlay();
//                }
//                setProgress(per);
                break;
            case MotionEvent.ACTION_POINTER_DOWN: {
                final int pointerIndex = ev.getActionIndex();
                final int pointerId = ev.getPointerId(pointerIndex);
                if (pointerId != mActivePointerId) {
                    mLastX = ev.getX(pointerIndex);
                    mActivePointerId = ev.getPointerId(pointerIndex);
                }
                break;
            }
            case MotionEvent.ACTION_POINTER_UP: {
                final int pointerIndex = ev.getActionIndex();
                final int pointerId = ev.getPointerId(pointerIndex);
                if (pointerId == mActivePointerId) {
                    final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                    mLastX = ev.getX(newPointerIndex);
                    mActivePointerId = ev.getPointerId(newPointerIndex);
                }
                break;
            }
            default:
                break;
        }

        return true;
    }


    private void doMove(float dx, float x, float y) {
        double atan = Math.atan((mHeight / 2 - y) / (x - mWidth / 2));
        double degrees = Math.toDegrees(atan);

        double realDegree = 0;
        if (x <= mWidth / 2 && y >= mHeight / 2) {
            realDegree = 35 - degrees;
        } else if (x <= mWidth / 2 && y < mHeight / 2) {
            realDegree = -(degrees - 35);
        } else if (x > mWidth / 2 && y >= mHeight / 2) {
            realDegree = 130 + (90 - degrees);
        } else if (x > mWidth / 2 && y < mHeight / 2) {
            realDegree = 230 - degrees;
        }

        if (realDegree <= 0) {
            realDegree = 0;
        }else if (realDegree > 270){
            realDegree = 270;
        }
        perPoint = (float) (realDegree / 270);

        if (mCompressViewListener != null){
            mCompressViewListener.onAdjustCompress(perPoint);
        }
        invalidate();

//        cgangePer();
    }

    private CompressViewListener mCompressViewListener;

    public void setCompressViewListener(CompressViewListener listener) {
        this.mCompressViewListener = listener;
    }

    public interface CompressViewListener {
        void getCompressValue(float percent);
        void onAdjustCompress(float value);
    }
}